﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using lumo.display.object2D;
using System.Collections;
using FarseerPhysics.Dynamics;
using FarseerPhysics.Factories;
using Microsoft.Xna.Framework;
using lumo;
using System.Text.RegularExpressions;
using FarseerPhysics.Dynamics.Contacts;
using lumo.display.light;
using Microsoft.Xna.Framework.Graphics;
using game.character;
using game.character.enemy;

namespace game.display.object2d
{
    /// <summary>
    /// Level class containing everything used.
    /// </summary>
    public class Tilemap
    {
        // Level variables
        public readonly float Width;
        public readonly float Height;
        
        // Private variables
        List<TileLayer>     LevelBackTileLayer  = new List<TileLayer>();
        List<TileLayer>     LevelMiddleTileLayer = new List<TileLayer>();
        List<TileLayer>     LevelFrontTileLayer = new List<TileLayer>();
        List<TileLayer>     CastShadowLayerList = new List<TileLayer>();
        List<TileLayer>     AllLayerList        = new List<TileLayer>();

        /// <summary>
        /// The level constructor.
        /// </summary>
        /// <param name="Tiled"></param>
        public Tilemap(lumo.LumoComponent LumoComponent, Tiled Map)
        {
            // Set variables.
            this.Width  = Map.Width * Map.TileHeight;
            this.Height = Map.Height * Map.TileHeight;

            // Iterate Through Each layer.
            foreach (Tiled.Layer Layer in Map.Layers)
            {
                // Check if it is a layer.
                if (Layer is Tiled.TileLayer)
                {
                    // Add the layer to the front or back data.
                    TileLayer TileLayer = new TileLayer(LumoComponent, Layer as Tiled.TileLayer);
                    if (!(Layer.Properties as IDictionary).Contains("Invisible"))
                    {
                        if ((Layer.Properties as IDictionary).Contains("Back"))
                            LevelBackTileLayer.Add(TileLayer);
                        else if ((Layer.Properties as IDictionary).Contains("Front"))
                            LevelFrontTileLayer.Add(TileLayer);
                        else
                            LevelMiddleTileLayer.Add(TileLayer);
                    }

                    // Layers that cast shadows.
                    if ((Layer.Properties as IDictionary).Contains("CastShadow"))
                        CastShadowLayerList.Add(TileLayer);

                    // Add the layer
                    AllLayerList.Add(TileLayer);
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="Tiled"></param>
        public void Clear()
        {
            LevelBackTileLayer.Clear();
            LevelMiddleTileLayer.Clear();
            LevelFrontTileLayer.Clear();
            CastShadowLayerList.Clear();
            AllLayerList.Clear();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="spriteBatch"></param>
        public void DrawBack(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch)
        {
            foreach (TileLayer obj in LevelBackTileLayer)
                obj.Draw(spriteBatch);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="spriteBatch"></param>
        public void DrawMiddle(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch)
        {
            foreach (TileLayer obj in LevelMiddleTileLayer)
                obj.Draw(spriteBatch);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="spriteBatch"></param>
        public void DrawFront(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch)
        {
            foreach (TileLayer obj in LevelFrontTileLayer)
                obj.Draw(spriteBatch);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="spriteBatch"></param>
        public void DrawCastShadow(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch)
        {
            foreach (TileLayer obj in CastShadowLayerList)
                obj.Draw(spriteBatch);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="component"></param>
        public void Update(LumoComponent component, Camera camera)
        {
            foreach (TileLayer layer in AllLayerList)
            {
                layer.Origin = camera.ScreenPosition * (LevelBackTileLayer.Contains(layer) ? 0.75f : 1);
            }
        }

    }

}
